package com.shengdong.water.code.utils

import android.os.Build
import com.shengdong.water.code.utils.pass.ByteUtils
import com.shengdong.water.code.utils.pass.SM4
import com.shengdong.water.code.utils.pass.SM4Context
import java.nio.charset.Charset
import java.util.Arrays
import java.util.Base64
import java.util.regex.Pattern

class SM4Util {

    companion object {
        private const val SECRET_KEY = "sdznky@123456789"
        private const val IV = "sdznky@123456789"
        private const val HEX_STRING = false


        //EC模式加密
        fun encryptDataECB(src: String): String? {
            return try {
                val ctx = SM4Context().apply {
                    isPadding = true
                    mode = SM4.SM4_ENCRYPT
                }

                val keyBytes = SECRET_KEY.toByteArray(Charsets.UTF_8)
                val sm4 = SM4()
                sm4.sm4_setkey_enc(ctx, keyBytes)
                val encrypted = sm4.sm4_crypt_ecb(ctx, src.toByteArray(Charsets.UTF_8))
                var cipherText =
                    Base64.getEncoder().encodeToString(encrypted)


                if (cipherText.isNotBlank()) {
                    val p = Pattern.compile("\\s*|\\t|\\r|\\n")
                    val m = p.matcher(cipherText)
                    cipherText = m.replaceAll("")
                }
                cipherText
            } catch (e: Exception) {
                e.printStackTrace();
                null
            }
        }

        //ECB模式解密
        fun decryptDataECB(src: String): String? {
            return try {
                val ctx = SM4Context().apply {
                    isPadding = true
                    mode = SM4.SM4_DECRYPT
                }

                val keyBytes = SECRET_KEY.toByteArray(Charsets.UTF_8)
                val sm4 = SM4()
                sm4.sm4_setkey_dec(ctx, keyBytes)

                val decrypted = sm4.sm4_crypt_ecb(
                    ctx, Base64.getDecoder().decode(src)
                )
                String(decrypted, Charsets.UTF_8)
            } catch (e: Exception) {
                e.printStackTrace();
                null
            }
        }


        //CBC模式 加密
        fun encryptDataCBC(src: String): String? {
            return try {
                val ctx = SM4Context().apply {
                    isPadding = true
                    mode = SM4.SM4_ENCRYPT
                }

                val keyBytes = SECRET_KEY.toByteArray(Charsets.UTF_8)
                val ivBytes = IV.toByteArray(Charsets.UTF_8)
                val sm4 = SM4()
                sm4.sm4_setkey_enc(ctx, keyBytes)
                val encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, src.toByteArray(Charsets.UTF_8))
                var cipherText = Base64.getEncoder().encodeToString(encrypted)
                if (cipherText.isNotBlank()) {
                    val p = Pattern.compile("\\s*|\\t|\\r|\\n")
                    val m = p.matcher(cipherText)
                    cipherText = m.replaceAll("")
                }
                cipherText
            } catch (e: Exception) {
                e.printStackTrace();
                null
            }
        }

        //CBC模式解密
        fun decryptDataCBC(src: String): String? {
            return try {
                val ctx = SM4Context().apply {
                    isPadding = true
                    mode = SM4.SM4_DECRYPT
                }

                val keyBytes: ByteArray
                val ivBytes: ByteArray
                if (HEX_STRING) {
                    keyBytes = ByteUtils.hexStringToBytes(SECRET_KEY)
                    ivBytes = ByteUtils.hexStringToBytes(IV)
                } else {
                    keyBytes = SECRET_KEY.toByteArray(Charsets.UTF_8)
                    ivBytes = IV.toByteArray(Charsets.UTF_8)
                }
                val sm4 = SM4()
                sm4.sm4_setkey_dec(ctx, keyBytes)

                val decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Base64.getDecoder().decode(src))
                String(decrypted, Charsets.UTF_8)
            } catch (e: Exception) {
                e.printStackTrace();
                null
            }
        }
    }
}



